home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / screen32.lha / screen-3.2b / socket.c < prev    next >
C/C++ Source or Header  |  1992-10-27  |  27KB  |  1,096 lines

  1. /* Copyright (c) 1991
  2.  *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  3.  *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  4.  * Copyright (c) 1987 Oliver Laumann
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 1, or (at your option)
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program (see the file COPYING); if not, write to the
  18.  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * Noteworthy contributors to screen's design and implementation:
  21.  *    Wayne Davison (davison@borland.com)
  22.  *    Patrick Wolfe (pat@kai.com, kailand!pat)
  23.  *    Bart Schaefer (schaefer@cse.ogi.edu)
  24.  *    Nathan Glasser (nathan@brokaw.lcs.mit.edu)
  25.  *    Larry W. Virden (lwv27%cas.BITNET@CUNYVM.CUNY.Edu)
  26.  *    Howard Chu (hyc@hanauma.jpl.nasa.gov)
  27.  *    Tim MacKenzie (tym@dibbler.cs.monash.edu.au)
  28.  *    Markku Jarvinen (mta@{cc,cs,ee}.tut.fi)
  29.  *    Marc Boucher (marc@CAM.ORG)
  30.  *
  31.  ****************************************************************
  32.  */
  33.  
  34. #ifndef lint
  35.   static char rcs_id[] = "$Id: socket.c,v 1.2 92/02/03 02:28:17 jnweiger Exp $ FAU";
  36. #endif
  37.  
  38. #include "config.h"
  39. #if defined(MIPS) || defined(GOULD_NP1) || defined(B43)
  40. extern int errno;
  41. #endif
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44. #ifndef sgi
  45. # include <sys/file.h>
  46. #endif
  47. #ifndef NAMEDPIPE
  48. #include <sys/socket.h>
  49. #endif
  50. #include <fcntl.h>
  51. #ifndef NAMEDPIPE
  52. #include <sys/un.h>
  53. #endif
  54. #include <signal.h>
  55. #ifndef M_XENIX
  56. #include <sys/time.h>
  57. #endif /* M_XENIX */
  58. #ifdef DIRENT
  59. # include <sys/param.h>
  60. # include <dirent.h>
  61. #else
  62. # include <sys/dir.h>
  63. # define dirent direct
  64. #endif
  65.  
  66. #include "screen.h"
  67.  
  68. #ifdef USEVARARGS
  69. # if defined(__STDC__)
  70. #  include <stdarg.h>
  71. # else
  72. #  include <varargs.h>
  73. # endif
  74. #endif
  75.  
  76. #include "extern.h"
  77.  
  78. #if defined(_SEQUENT_) && !defined(NAMEDPIPE)
  79. # define connect sconnect    /* _SEQUENT_ has braindamaged connect */
  80. #endif
  81.  
  82. extern char *RcFileName, *extra_incap, *extra_outcap;
  83. extern WinList, Detached, ServerSocket, real_uid, real_gid, eff_uid, eff_gid;
  84. #ifdef BSDJOBS
  85. extern int Suspended;
  86. #endif
  87. extern AttacherPid, dflag, rflag, lsflag, quietflag, wipeflag;
  88. extern char HostName[];
  89. extern struct mode OldMode, NewMode;
  90. extern char display_tty[];
  91. extern struct win *wtab[], *fore;
  92. #ifdef NETHACK
  93. extern nethackflag;
  94. #endif
  95.  
  96. #ifdef PASSWORD
  97. extern int CheckPassword;
  98. extern char Password[];
  99. #endif
  100. #if defined(BSDJOBS) && !(defined(POSIX) || defined(SYSV))
  101. extern DevTty;
  102. #endif
  103. extern char *getenv();
  104.  
  105. char SockPath[MAXPATH];
  106. char *SockNamePtr, *SockName;
  107.  
  108. char *strdup(str)
  109. #ifdef hpux
  110. char *str;
  111. #else
  112. const char *str;
  113. #endif
  114. {
  115.   char *ret;
  116.  
  117.   if ((ret = (char *) malloc(strlen(str) + 1)) == 0)
  118.     {
  119.       Msg_nomem;
  120.       return (0);
  121.     }
  122.   (void) strcpy(ret, str);
  123.   return (ret);
  124. }
  125.  
  126. int RecoverSocket()
  127. {
  128.   int s = 0, d;
  129.  
  130.   (void) unlink(SockPath);
  131.   s = MakeServerSocket();
  132.   if (s != ServerSocket)
  133.     {
  134.       debug2("Oh, Serversocket was %d, now %d, let's dup!\n", ServerSocket, s);
  135.       d = dup2(s, ServerSocket);
  136.       close(s);
  137.       if (d != ServerSocket)
  138.     {
  139.       debug2("Hmm, dup2() failed, Serversocket was %d, now %d, bye\n",
  140.          ServerSocket, d);
  141.       return 0;
  142.     }
  143.     }
  144.   if (Detached)
  145.     (void) chmod(SockPath, /* S_IFSOCK | */ 0600); /* Flag detached-ness */
  146.   return 1;
  147. }
  148.  
  149. /*
  150.  * Socket mode 700 means we are Attached. 600 is detached.
  151.  * We return how many sockets we found. If it was exactly one, we come
  152.  * back with a SockPath set to it and open it in a fd pointed to by fdp.
  153.  * If fdp == 0 we simply produce a list if all sockets.
  154.  */
  155. int FindSocket(how, fdp)
  156. int how;
  157. int *fdp;
  158. {
  159.   register int s, lasts = 0, found = 0, deadcount = 0, wipecount = 0;
  160.   register int l;
  161.   register DIR *dirp;
  162.   register struct dirent *dp;
  163.   register char *Name;
  164.   struct stat st;
  165.   struct foundsock
  166.     {
  167.       char *name;
  168.       int mode;
  169.     } foundsock[100];    /* 100 is hopefully enough. */
  170.   int foundsockcount = 0;
  171.  
  172.   /* User may or may not give us a (prefix) SockName. We want to search. */
  173.   debug("FindSocket:\n");
  174.   if (SockName)
  175.     {
  176.       debug1("We want to match '%s'\n", SockName);
  177.       l = strlen(SockName);
  178. #ifdef NAME_MAX
  179.       if (l > NAME_MAX)
  180.     l = NAME_MAX;
  181. #endif
  182.     }
  183.  
  184. #ifdef NFS_HACK
  185.   setreuid(eff_uid, real_uid);
  186. #endif
  187.   debug1("FindSock searching... '%s'\n", SockPath);
  188.   /*
  189.    * this is a hack: SockName may point to Filename(Sockpath)...
  190.    */
  191.   found = *SockNamePtr;
  192.   *SockNamePtr = '\0';
  193.   if ((dirp = opendir(SockPath)) == NULL)
  194.     {
  195.       Msg(0, "Cannot opendir %s", SockPath);
  196.       /* NOTREACHED */
  197.     }
  198.   *SockNamePtr = found;
  199.   found = 0;
  200.   while ((dp = readdir(dirp)) != NULL)
  201.     {
  202.       Name = dp->d_name;
  203.       /* 
  204.        * there may be a file ".termcap" here. 
  205.        * Ignore it just like "." and "..". 
  206.        */
  207.       if (Name[0] == '.')
  208.     continue;
  209.       debug2("Attach found: '%s', needed '%s'\n", Name, SockName);
  210.       if (SockName && l)
  211.     {
  212.       register char *n = Name;
  213.  
  214.       /*
  215.        * The SockNames "hf", "ttyhf", "1", "12345.tty", "12345.ttyhf.medusa"
  216.        * all match the Name "12345.ttyhf.medusa".
  217.        */
  218.  
  219.       if ((*SockName <= '0' || *SockName > '9') && (*n > '0' && *n <= '9'))
  220.         {
  221.           while (*++n)
  222.         if (*n == '.')
  223.           {
  224.             n++;
  225.             break;
  226.           }
  227.           if (strncmp("tty", SockName, 3) && !strncmp("tty", n, 3))
  228.         n += 3;
  229.         }
  230.       if (strncmp(n, SockName, l))
  231.         {
  232.           debug3("strncmp('%s', '%s', %d)\n", n, SockName, l);
  233.           continue;
  234.         }
  235.     }
  236.       /*
  237.        * ATTENTION! MakeClientSocket adds SockName to SockPath! 
  238.        * Anyway, we need it earlier.
  239.        */
  240.       strcpy(SockNamePtr, Name);
  241.       if (stat(SockPath, &st))
  242.     continue;
  243.       if (st.st_uid != real_uid)
  244.     continue;
  245.       foundsock[foundsockcount].name = strdup(Name);
  246.       foundsock[foundsockcount].mode = s = st.st_mode & 0777;
  247.       debug2("FindSocket: %s has mode %04o...\n", Name, s);
  248.       if (s == 0700 || s == 0600)
  249.     {
  250.       /*
  251.        * We try to connect through the socket. If successfull, 
  252.        * thats o.k. Otherwise we record that mode as -1.
  253.        * MakeClientSocket() must be careful not to block forever.
  254.        */
  255.       if ((s = MakeClientSocket(0, Name)) == -1)
  256.         { 
  257.           foundsock[foundsockcount].mode = -1;
  258.           deadcount++;
  259.         }
  260.       else
  261.         close(s);
  262.     }
  263.       if (++foundsockcount >= 100)
  264.     break;
  265.     }
  266.   closedir(dirp);
  267. #ifdef NFS_HACK
  268.   setreuid(real_uid, eff_uid);
  269. #endif
  270.  
  271.   if (wipeflag)
  272.     {
  273.       for (s = 0; s < foundsockcount; s++)
  274.     {
  275.       if (foundsock[s].mode == -1)
  276.         {
  277.               strcpy(SockNamePtr, foundsock[s].name);
  278.           debug1("wiping '%d'\n", SockPath);
  279.           if (unlink(SockPath) == 0)
  280.             {
  281.           foundsock[s].mode = -2;
  282.               wipecount++;
  283.         }
  284.         }
  285.     }
  286.     }
  287.   for (s = 0; s < foundsockcount; s++)
  288.     if ((foundsock[s].mode) == (dflag ? 0700 : 0600)) 
  289.       {
  290.     found++;
  291.     lasts = s;
  292.       }
  293.   if (quietflag && (lsflag || (found != 1 && rflag != 2)))
  294.     eexit(10 + found);
  295.   debug2("attach: found=%d, foundsockcount=%d\n", found, foundsockcount);
  296.   if (found == 1 && lsflag == 0)
  297.     {
  298.       if ((lasts = MakeClientSocket(0, SockName = foundsock[lasts].name)) == -1)
  299.         found = 0;
  300.     }
  301.   else if (!quietflag && foundsockcount > 0)
  302.     {
  303.       switch (found)
  304.         {
  305.         case 0:
  306.           if (lsflag)
  307.         {
  308. #ifdef NETHACK
  309.               if (nethackflag)
  310.             printf("Your inventory:\n");
  311.           else
  312. #endif
  313.           printf((foundsockcount > 1) ?
  314.                  "There are screens on:\n" : "There is a screen on:\n");
  315.         }
  316.           else
  317.         {
  318. #ifdef NETHACK
  319.               if (nethackflag)
  320.             printf("Nothing fitting exists in the game:\n");
  321.           else
  322. #endif
  323.           printf((foundsockcount > 1) ?
  324.                  "There are screens on:\n" : "There is a screen on:\n");
  325.         }
  326.           break;
  327.         case 1:
  328. #ifdef NETHACK
  329.           if (nethackflag)
  330.             printf((foundsockcount > 1) ?
  331.                    "Prove thyself worthy or perish:\n" : 
  332.                    "You see here a good looking screen:\n");
  333.           else
  334. #endif
  335.           printf((foundsockcount > 1) ? 
  336.                  "There are several screens on:\n" :
  337.                  "There is a possible screen on:\n");
  338.           break;
  339.         default:
  340. #ifdef NETHACK
  341.           if (nethackflag)
  342.             printf((foundsockcount > 1) ? 
  343.                    "You may whish for a screen, what do you want?\n" : 
  344.                    "You see here a screen:\n");
  345.           else
  346. #endif
  347.           printf((foundsockcount > 1) ?
  348.                  "There are several screens on:\n" : "There is a screen on:\n");
  349.           break;
  350.         }
  351.       for (s = 0; s < foundsockcount; s++)
  352.     {
  353.       switch (foundsock[s].mode)
  354.         {
  355.         case 0700:
  356.           printf("\t%s\t(Attached)\n", foundsock[s].name);
  357.           break;
  358.         case 0600:
  359.           printf("\t%s\t(Detached)\n", foundsock[s].name);
  360.           break;
  361.         case -1:
  362. #if defined(__STDC__) || defined(_AIX)
  363.           printf("\t%s\t(Dead ??\?)\n", foundsock[s].name);
  364. #else
  365.           printf("\t%s\t(Dead ???)\n", foundsock[s].name);
  366. #endif
  367.           break;
  368.         case -2:
  369.           printf("\t%s\t(Removed)\n", foundsock[s].name);
  370.           break;
  371.         default:
  372.           printf("\t%s\t(Wrong mode)\n", foundsock[s].name);
  373.           break;
  374.         }
  375.     }
  376.     }
  377.   if (deadcount && !quietflag)
  378.     {
  379.       if (wipeflag)
  380.         {
  381. #ifdef NETHACK
  382.           if (nethackflag)
  383.             printf("You hear%s distant explosion%s.\n",
  384.            (deadcount > 1) ? "" : " a", (deadcount > 1) ? "s" : "");
  385.           else
  386. #endif
  387.           printf("%d Socket%s wiped out.\n", deadcount, (deadcount > 1)?"s":"");
  388.     }
  389.       else
  390.     {
  391. #ifdef NETHACK
  392.           if (nethackflag)
  393.             printf("The dead screen%s touch%s you. Try 'screen -wipe'.\n",
  394.            (deadcount > 1) ? "s" : "", (deadcount > 1) ? "" : "es");
  395.           else
  396. #endif
  397.           printf("Remove dead Sockets with 'screen -wipe'.\n");
  398.     }
  399.     }
  400.  
  401.   for (s = 0; s < foundsockcount; s++)
  402.     Free(foundsock[s].name);
  403.   if (found == 1 && fdp)
  404.     *fdp = lasts;
  405.   if (fdp)
  406.     return found;
  407.   return foundsockcount - wipecount;
  408. }
  409.  
  410. #ifdef NAMEDPIPE
  411.  
  412. int
  413. MakeServerSocket()
  414. {
  415.   register int s;
  416.   struct stat st;
  417.  
  418.   strcpy(SockNamePtr, SockName);
  419. #ifdef NAME_MAX
  420.   if (strlen(SockNamePtr) > NAME_MAX)
  421.     {
  422.       debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  423.          SockNamePtr, NAME_MAX);
  424.       SockNamePtr[NAME_MAX] = '\0';
  425.     }
  426. #endif
  427.  
  428.   if ((s = open(SockPath, O_WRONLY | O_NDELAY)) >= 0)
  429.     {
  430.       debug("huii, my fifo already exists??\n");
  431.       if (quietflag)
  432.     {
  433.       Kill(AttacherPid, SIG_BYE);
  434.       eexit(11);
  435.     }
  436.       printf("There is already a screen running on %s.\n",
  437.          Filename(SockPath));
  438.       if (stat(SockPath, &st) == -1)
  439.     Msg(errno, "stat");
  440.       if (st.st_uid != real_uid)
  441.     Msg(0, "Unfortunatelly you are not its owner.");
  442.       if ((st.st_mode & 0700) == 0600)
  443.     Msg(0, "To resume it, use \"screen -r\"");
  444.       else
  445.     Msg(0, "It is not detached.");
  446.       /* NOTREACHED */
  447.     }
  448.   (void) unlink(SockPath);
  449.   if (UserContext() > 0)
  450.     {
  451. #if defined(_POSIX_SOURCE) && defined(ISC)
  452.       if (mknod(SockPath, 0010700, 0))
  453. #else
  454.       if (mknod(SockPath, S_IFIFO | S_IEXEC | S_IWRITE | S_IREAD, 0))
  455. #endif
  456.     UserReturn(0);
  457.       UserReturn(1);
  458.     }
  459.   if (UserStatus() <= 0)
  460.     Msg(0, "mknod fifo %s failed", SockPath);
  461.   /*
  462.    * MUST be RDWR because otherwise we will get EOF's if
  463.    * nobody has opened the pipe for writing
  464.    */
  465.   if ((s = secopen(SockPath, O_RDWR | O_NDELAY, 0)) < 0)
  466.     Msg(errno, "open fifo %s", SockPath);
  467.   return s;
  468. }
  469.  
  470.  
  471. int
  472. MakeClientSocket(err, name)
  473. int err;
  474. char *name;
  475. {
  476.   register int s = 0;
  477.  
  478.   strcpy(SockNamePtr, name);
  479. #ifdef NAME_MAX
  480.   if (strlen(SockNamePtr) > NAME_MAX)
  481.     {
  482.       debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  483.          SockNamePtr, NAME_MAX);
  484.       SockNamePtr[NAME_MAX] = '\0';
  485.     }
  486. #endif
  487.   
  488.   if ((s = secopen(SockPath, O_WRONLY | O_NDELAY, 0)) >= 0)
  489.     {
  490.       (void) fcntl(s, F_SETFL, 0);
  491.       return s;
  492.     }
  493.   if (err)
  494.     {
  495.       Msg(errno, "open: %s (but continuing...)", SockPath);
  496.       debug1("MakeClientSocket() open %s failed\n", SockPath);
  497.     }
  498.   else
  499.     {
  500.       debug1("MakeClientSocket() open %s failed\n", SockPath);
  501.     }
  502.   return -1;
  503. }
  504.  
  505. #else    /* NAMEDPIPE */
  506.  
  507. int
  508. MakeServerSocket()
  509. {
  510.   register int s;
  511.   struct sockaddr_un a;
  512.   struct stat st;
  513.  
  514.   if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  515.     Msg(errno, "socket");
  516.   a.sun_family = AF_UNIX;
  517.   strcpy(SockNamePtr, SockName);
  518. #ifdef NAME_MAX
  519.   if (strlen(SockNamePtr) > NAME_MAX)
  520.     {
  521.       debug2("MakeServerSocket: '%s' truncated to %d chars\n",
  522.          SockNamePtr, NAME_MAX);
  523.       SockNamePtr[NAME_MAX] = '\0';
  524.     }
  525. #endif
  526.  
  527.   strcpy(a.sun_path, SockPath);
  528.   if (connect(s, (struct sockaddr *) & a, strlen(SockPath) + 2) != -1)
  529.     {
  530.       debug("oooooh! socket already is alive!\n");
  531.       if (quietflag)
  532.     { 
  533.       Kill(AttacherPid, SIG_BYE);
  534.       /* 
  535.        * oh, well. nobody receives that return code. papa 
  536.        * dies by signal.
  537.        */
  538.       eexit(11);
  539.     }
  540.       printf("There is already a screen running on %s.\n",
  541.          Filename(SockPath));
  542.       if (stat(SockPath, &st) == -1)
  543.     Msg(errno, "stat");
  544.       if (st.st_uid != real_uid)
  545.     Msg(0, "Unfortunatelly you are not its owner.");
  546.       if ((st.st_mode & 0700) == 0600)
  547.     Msg(0, "To resume it, use \"screen -r\"");
  548.       else
  549.     Msg(0, "It is not detached.");
  550.       /* NOTREACHED */
  551.     }
  552.   (void) unlink(SockPath);
  553. #ifndef NOREUID
  554.   setreuid(eff_uid, real_uid);
  555.   setregid(eff_gid, real_gid);
  556. #endif
  557.   if (bind(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
  558.     Msg(errno, "bind");
  559.   (void) chmod(SockPath, /* S_IFSOCK | */ 0700);
  560. #ifdef NOREUID
  561.   chown(SockPath, real_uid, real_gid);
  562. #else
  563.   setreuid(real_uid, eff_uid);
  564.   setregid(real_gid, eff_gid);
  565. #endif
  566.   if (listen(s, 5) == -1)
  567.     Msg(errno, "listen");
  568. #ifdef F_SETOWN
  569.   fcntl(s, F_SETOWN, getpid());
  570.   debug1("Serversocket owned by %d\n", fcntl(s, F_GETOWN, 0));
  571. #endif /* F_SETOWN */
  572.   return s;
  573. }
  574.  
  575. int
  576. MakeClientSocket(err, name)
  577. int err;
  578. char *name;
  579. {
  580.   register int s;
  581.   struct sockaddr_un a;
  582.  
  583.   if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  584.     Msg(errno, "socket");
  585.   a.sun_family = AF_UNIX;
  586.   strcpy(SockNamePtr, name);
  587. #ifdef NAME_MAX
  588.   if (strlen(SockNamePtr) > NAME_MAX)
  589.     {
  590.       debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  591.          SockNamePtr, NAME_MAX);
  592.       SockNamePtr[NAME_MAX] = '\0';
  593.     }
  594. #endif
  595.  
  596.   strcpy(a.sun_path, SockPath);
  597. #ifndef NOREUID
  598.   setreuid(eff_uid, real_uid);
  599.   setregid(eff_gid, real_gid);
  600. #else
  601.   if (access(SockPath, W_OK))
  602.     {
  603.       if (err)
  604.     Msg(errno, "%s", SockPath);
  605.       else
  606.     debug2("MakeClientSocket: access(%s): %d.\n", SockPath, errno);
  607.       close(s);
  608.       return -1;
  609.     }
  610. #endif
  611.   if (connect(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
  612.     {
  613.       if (err)
  614.     Msg(errno, "%s: connect", SockPath);
  615.       else
  616.     debug("MakeClientSocket: connect failed.\n");
  617.       close(s);
  618.       s = -1;
  619.     }
  620. #ifndef NOREUID
  621.   setreuid(real_uid, eff_uid);
  622.   setregid(real_gid, eff_gid);
  623. #endif
  624.   return s;
  625. }
  626. #endif
  627.  
  628.  
  629. void
  630. SendCreateMsg(s, ac, av, aflag, flowflag, lflag, histheight, sterm)
  631. int s, ac, aflag, flowflag, lflag, histheight;
  632. char **av;
  633. char *sterm;
  634. {
  635.   struct msg m;
  636.   register char *p;
  637.   register int len, n;
  638.  
  639.   debug1("SendCreateMsg() to '%s'\n", SockPath);
  640.   m.type = MSG_CREATE;
  641.   p = m.m.create.line;
  642.   for (n = 0; ac > 0 && n < MAXARGS - 1; ++av, --ac, ++n)
  643.     {
  644.       len = strlen(*av) + 1;
  645.       if (p + len >= m.m.create.line + MAXPATH - 1)
  646.     break;
  647.       strcpy(p, *av);
  648.       p += len;
  649.     }
  650.   if (!ac && *av && p + strlen(*av) + 1 < m.m.create.line + MAXPATH)
  651.     strcpy(p, *av);
  652.   else
  653.     *p = '\0';
  654.   m.m.create.nargs = n;
  655.   m.m.create.aflag = aflag;
  656.   m.m.create.flowflag = flowflag;
  657.   m.m.create.lflag = lflag;
  658.   m.m.create.hheight = histheight;
  659. #ifdef SYSV
  660.   if (getcwd(m.m.create.dir, sizeof(m.m.create.dir)) == 0)
  661. #else
  662.     if (getwd(m.m.create.dir) == 0)
  663. #endif
  664.       Msg(0, "%s", m.m.create.dir);
  665.   strncpy(m.m.create.screenterm, sterm, 19);
  666.   m.m.create.screenterm[19] = '\0';
  667.   debug1("SendCreateMsg writing '%s'\n", m.m.create.line);
  668.   if (write(s, (char *) &m, sizeof m) != sizeof m)
  669.     Msg(errno, "write");
  670. }
  671.  
  672. void
  673. #ifdef USEVARARGS
  674. /*VARARGS1*/
  675. # if defined(__STDC__)
  676. SendErrorMsg(char *fmt, ...)
  677. # else
  678. SendErrorMsg(fmt, va_alist)
  679. char *fmt;
  680. va_dcl
  681. #endif
  682. { /* } */
  683.   static va_list ap = 0;
  684. #else
  685. /*VARARGS1*/
  686. SendErrorMsg(fmt, p1, p2, p3, p4, p5, p6)
  687. char *fmt;
  688. unsigned long p1, p2, p3, p4, p5, p6;
  689. {
  690. #endif
  691.   register int s;
  692.   struct msg m;
  693.  
  694.   s = MakeClientSocket(1, SockName);
  695.   debug1("SendErrorMsg() to '%s'\n", SockPath);
  696.   m.type = MSG_ERROR;
  697. #ifdef USEVARARGS
  698. # if defined(__STDC__)
  699.   va_start(ap, fmt);
  700. # else
  701.   va_start(ap);
  702. # endif
  703.   (void) vsprintf(m.m.message, fmt, ap);
  704.   va_end(ap);
  705. #else
  706.   sprintf(m.m.message, fmt, p1, p2, p3, p4, p5, p6);
  707. #endif
  708.   debug1("SendErrorMsg writing '%s'\n", m.m.message);
  709.   (void) write(s, (char *) &m, sizeof m);
  710.   close(s);
  711.   sleep(2);
  712. }
  713.  
  714. #ifdef PASSWORD
  715. static int CheckPasswd(pwd, pid, tty)
  716. int pid;
  717. char *pwd, *tty;
  718. {
  719.   if (CheckPassword && 
  720.       strcmp(crypt(pwd, (strlen(Password) > 1) ? Password : "JW"),
  721.          Password))
  722.     {
  723.       if (*pwd)
  724.     {
  725. #ifdef NETHACK
  726.           if (nethackflag)
  727.         Msg(0, "'%s' tries to explode in the sky, but fails. (%s)", tty, pwd);
  728.           else
  729. #endif
  730.       Msg(0, "Illegal reattach attempt from terminal %s, \"%s\"", tty, pwd);
  731.     }
  732.       debug1("CheckPass() wrong password kill(%d, SIG_PW_FAIL)\n", pid);
  733.       Kill(pid, SIG_PW_FAIL);
  734.       return 0;
  735.     }
  736.   debug1("CheckPass() from %d happy\n", pid);
  737.   Kill(pid, SIG_PW_OK);
  738.   return 1;
  739. }
  740. #endif    /* PASSWORD */
  741.  
  742. static void ExecCreate(mp)
  743. struct msg *mp;
  744. {
  745.   char *args[MAXARGS];
  746.   register int n;
  747.   register char **pp = args, *p = mp->m.create.line;
  748.  
  749.   for (n = mp->m.create.nargs; n > 0; --n)
  750.     {
  751.       *pp++ = p;
  752.       p += strlen(p) + 1;
  753.     }
  754.   *pp = 0;
  755.   if (!*p)
  756.     p = 0;
  757.   MakeWindow(p, args, mp->m.create.aflag, mp->m.create.flowflag,
  758.               0, mp->m.create.dir, mp->m.create.lflag,
  759.               mp->m.create.hheight, mp->m.create.screenterm);
  760. }
  761.  
  762. static int
  763. CheckPid(pid)
  764. int pid;
  765. {
  766.   if (pid < 2)
  767.     return(-1);
  768.   if (eff_uid == real_uid)
  769.     return kill(pid, 0);
  770.   if (UserContext() == 1)
  771.     {
  772.       UserReturn(kill(pid, 0));
  773.     }
  774.   return UserStatus();
  775. }
  776.  
  777. void
  778. ReceiveMsg(s)
  779. int s;
  780. {
  781.   int left, len, i;
  782.   static struct msg m;
  783.   char *p;
  784.   static char lbuf[20], cbuf[20]; /* static for later putenv()'s */
  785. #ifdef NAMEDPIPE
  786.   /*
  787.    * we may be called if there are no pending messages, so we will have to
  788.    * block on first read.
  789.    */
  790.   debug("Ha, there was someone knocking on my fifo??\n");
  791.   if (fcntl(s, F_SETFL, 0) == -1)
  792.     {
  793.       Msg(errno, "fcntl no O_NDELAY");
  794.       exit(1);
  795.     }
  796.   p = (char *) &m;
  797.   left = sizeof(m);
  798.   while (left > 0 && (len = read(s, p, left)) > 0)
  799.     {
  800.       /*        if (p == (char *)&m)
  801.        *        {    if (fcntl(s, F_SETFL, O_NDELAY) == -1)
  802.        *            {    Msg(errno, "fcntl O_NDELAY !");
  803.        *                return;
  804.        *            }
  805.        *        }
  806.        */
  807.       p += len;
  808.       left -= len;
  809.     }
  810. # ifdef DEBUG
  811.   if (len == 0)
  812.     debug("ReceiveMsg: Yucc! Got an EOF !!\n");
  813. # endif
  814. #else
  815.   register int ns;
  816.   struct sockaddr_un a;
  817.  
  818.   len = sizeof(struct sockaddr_un);
  819.   debug("Ha, there was someone knocking on my socket??\n");
  820.   if ((ns = accept(s, (struct sockaddr *) & a, &len)) == -1)
  821.     {
  822.       Msg(errno, "accept");
  823.       return;
  824.     }
  825.   p = (char *) &m;
  826.   left = sizeof m;
  827.   while (left > 0 && (len = read(ns, p, left)) > 0)
  828.     {
  829.       p += len;
  830.       left -= len;
  831.     }
  832.   close(ns);
  833. #endif                /* NAMEDPIPE */
  834.  
  835.   if (len == -1)
  836.     Msg(errno, "read");
  837.   if (left > 0)
  838.     return;
  839.   debug1("RecMsg: type %d !, ", m.type);
  840.   switch (m.type)
  841.     {
  842.     case MSG_WINCH:
  843.       /* Already processed in screen.c */
  844. #ifdef notdef
  845.       CheckScreenSize(1); /* Change fore */
  846. #endif
  847.       break;
  848.     case MSG_CREATE:
  849.       if (!Detached)
  850.     ExecCreate(&m);
  851.       break;
  852.     case MSG_CONT:
  853.       debug3("RecMsg: apid=%d,was %d, Detached=%d\n", m.m.attach.apid,
  854.              AttacherPid, Detached);
  855.  
  856. #ifdef SECURE_MSG_CONT
  857.       if (m.m.attach.apid != AttacherPid || !Detached)
  858.     /*
  859.      * now we realize, that there is something strange happening.
  860.      * First, there was some idiot who said "CONT" and thought
  861.      * "ATTACH". This is, when we have (AttacherPid == 0). Harmless.
  862.      * Let him in. Second, we are waiting for a certain AttacherPid,
  863.      * and not for "any" attacher. This is when (AttacherPid != 0).
  864.      * But Darwin's rule says "survival of the fittest", thus: Look
  865.      * weather "our" AttacherPid is still alive and well, and let the
  866.      * new one only in, if the old Attacher has been killed. jw.
  867.      */
  868.     if (AttacherPid != 0 && kill(AttacherPid, 0) == 0)
  869.       break;        /* Intruder Alert */
  870.     else
  871. #endif                /* SECURE_MSG_CONT */
  872.       AttacherPid = 0;    /* we dont want to kill ourselves
  873.                  * later. jw. */
  874.       /* FALLTHROUGH */
  875.     case MSG_ATTACH:
  876.       if (CheckPid(m.m.attach.apid))
  877.     {
  878.       debug1("Attach attempt with bad pid(%d)\n", m.m.attach.apid);
  879.       Msg(0, "Attach attempt with bad pid(%d) !", m.m.attach.apid);
  880.           break;
  881.     }
  882. #ifdef PASSWORD
  883.       if (!CheckPasswd(m.m.attach.password, m.m.attach.apid, m.m.attach.tty))
  884.     {
  885.       debug3("RcvMsg:Checkpass(%s,%d,%s) failed\n",
  886.          m.m.attach.password, m.m.attach.apid, m.m.attach.tty);
  887.       break;
  888.     }
  889. #endif                /* PASSWORD */
  890.       if (!Detached)
  891.     {
  892.       debug("RecMsg: hey, why you disturb, we are not detached. hangup!\n");
  893.       Kill(m.m.attach.apid, SIG_BYE);
  894.       Msg(0, "Attach msg ignored: We are not detached.");
  895.       break;
  896.     }
  897. #ifdef notdef
  898.       if ((i = secopen(m.m.attach.tty, O_RDWR | O_NDELAY, 0)) < 0)
  899. #else
  900.       if ((i = secopen(m.m.attach.tty, O_RDWR, 0)) < 0)
  901. #endif
  902.     {
  903.       debug1("ALERT: Cannot open %s!\n", m.m.attach.tty);
  904. #ifdef NETHACK
  905.           if (nethackflag)
  906.         Msg(errno, 
  907.             "You can't open (%s). Perhaps there's a Monster behind it.",
  908.             m.m.attach.tty);
  909.           else
  910. #endif
  911.       Msg(errno, "Attach: Could not open %s", m.m.attach.tty);
  912.       Kill(m.m.attach.apid, SIG_BYE);
  913.       break;
  914.     }
  915.       errno = 0;
  916.       if (i)
  917.     {
  918.       debug("PANIC: open did not return fd 0!\n");
  919.       close(0);
  920.       dup(i);
  921.       close(i);
  922.       close(1);
  923.       close(2);
  924.     }
  925.       debug2("RecMsg: apid %d is o.k. and we just opened '%s'\n", m.m.attach.apid, m.m.attach.tty);
  926.  
  927. #ifdef hpux_and_it_still_does_not_work
  928.       {
  929.     int pgrp, zero = 0;
  930.  
  931.     if (ioctl(0, TIOCGPGRP, &pgrp) == -1)
  932.       debug1("tcgetpgrp: %d\n", errno);    /* save old pgrp from tty */
  933.  
  934.     if (ioctl(0, TIOCSPGRP, &zero) == -1)
  935.       debug1("tcsetpgrp: %d\n", errno);    /* detach tty from proc grp */
  936. #ifdef hpux
  937.     setpgrp();
  938. #else
  939.     if (setpgrp(0, getpid()) == -1)
  940.       debug1("setpgrp: %d\n", errno);    /* make me proc group leader */
  941. #endif
  942.  
  943.     close(0);    /* reopen tty, now we should get it as our tty */
  944. #ifdef notdef
  945.     (void)secopen(m.m.attach.tty, O_RDWR | O_NDELAY, 0);    /* */
  946. #else
  947.     (void)secopen(m.m.attach.tty, O_RDWR, 0);       /* */
  948. #endif
  949.  
  950. #ifdef hpux
  951.     setpgrp2(0, pgrp);
  952. #else
  953.     setpgrp(0, pgrp);
  954. #endif
  955.     ioctl(0, TIOCSPGRP, &pgrp);
  956.       }
  957. #endif  /* hpux_and_it_still_does_not_work */
  958.  
  959.       (void) dup(0);
  960.       (void) dup(0);
  961.       GetTTY(0, &OldMode);
  962. #if defined(BSDJOBS) && !(defined(POSIX) || defined(SYSV))
  963.       if ((DevTty = open("/dev/tty", O_RDWR | O_NDELAY)) == -1)
  964.     {
  965.       debug1("DevTty not opened: %d.\n", errno);
  966.       Msg(errno, "/dev/tty");
  967.     }
  968. #endif
  969.       signal(SIGHUP, SigHup);
  970. #ifdef BSDJOBS
  971.       if (Suspended && m.type == MSG_ATTACH)
  972.     if (kill(AttacherPid, SIG_BYE) == 0)
  973.       kill(AttacherPid, SIGCONT);
  974. #endif
  975.  
  976.       AttacherPid = m.m.attach.apid;
  977.       strcpy(display_tty, m.m.attach.tty);
  978. #ifdef UTMPOK
  979.       /*
  980.        * we set the Utmp slots again, if we were detached normally
  981.        * and if we were detached by ^Z.
  982.        */
  983.       ReInitUtmp();
  984.       for (i = WinList; i != -1; i = wtab[i]->WinLink)
  985.     if (wtab[i]->slot != (slot_t) -1)
  986.       SetUtmp(wtab[i], i);
  987. #endif
  988.       (void) chmod(SockPath, /* S_IFSOCK | */ 0700);
  989.       Detached = 0;
  990. #ifdef BSDJOBS
  991.       Suspended = 0;
  992. #endif
  993.       /*
  994.        * we like to have always the valid termcap, even if we are
  995.        * reattached from a different tty type. thus attacher had to
  996.        * tell us, what TERM we have. The attacher has correct env
  997.        * setting. we (the backend may be wrong).
  998.        */
  999.       if (*m.m.attach.envterm)
  1000.     {
  1001. #if defined(pyr) || defined(xelos) || defined(sequent)
  1002.       /*
  1003.        * Kludge for systems with braindamaged termcap routines,
  1004.        * which evaluate $TERMCAP, regardless weather it describes
  1005.        * the correct terminal type or not.
  1006.        */
  1007.       if (strcmp(getenv("TERM"), m.m.attach.envterm + 5))
  1008.         {
  1009.           debug("a different terminal, so unsetenv(TERMCAP)");
  1010.           unsetenv("TERMCAP");
  1011.         }
  1012. #endif
  1013.     
  1014.       putenv(m.m.attach.envterm);
  1015.     }
  1016.       sprintf(lbuf, "LINES=%d", m.m.attach.lines);
  1017.       if (m.m.attach.lines > 0 || getenv("LINES"))
  1018.         putenv(lbuf);
  1019.       sprintf(cbuf, "COLUMNS=%d", m.m.attach.columns);
  1020.       if (m.m.attach.columns > 0 || getenv("COLUMNS"))
  1021.         putenv(cbuf);
  1022.       
  1023.       /*
  1024.        * We reboot our Terminal Emulator. Forget all we knew about
  1025.        * the old terminal, reread the termcap entries in .screenrc
  1026.        * (and nothing more from .screenrc is read. Mainly because
  1027.        * I did not check, weather a full reinit is save. jw) 
  1028.        * and /etc/screenrc, and initialise anew.
  1029.        */
  1030.       if (extra_outcap)
  1031.     Free(extra_outcap);
  1032.       if (extra_incap)
  1033.     Free(extra_incap);
  1034. #ifdef ETCSCREENRC
  1035.       if ((p = getenv("SYSSCREENRC")) == NULL)
  1036.     StartRc(ETCSCREENRC);
  1037.       else
  1038.     StartRc(p);
  1039. #endif
  1040.       StartRc(RcFileName);
  1041.       InitTermcap();
  1042.       InitTerm(m.m.attach.adaptflag);
  1043.       SetMode(&OldMode, &NewMode);
  1044.       SetTTY(0, &NewMode);
  1045.       fore->active = 1;
  1046.       Activate(0);
  1047.       debug("activated...\n");
  1048.       break;
  1049.     case MSG_ERROR:
  1050.       Msg(0, "%s", m.m.message);
  1051.       break;
  1052.     case MSG_HANGUP:
  1053. #ifdef REMOTE_DETACH
  1054.     case MSG_DETACH:
  1055. # ifdef POW_DETACH
  1056.     case MSG_POW_DETACH:
  1057. # endif                /* POW_DETACH */
  1058. #endif
  1059. #ifdef REMOTE_DETACH
  1060. # ifdef POW_DETACH
  1061.       if (m.type == MSG_POW_DETACH)
  1062.     Detach(D_REMOTE_POWER);
  1063.       else
  1064. # endif                /* POW_DETACH */
  1065.       if (m.type == MSG_DETACH)
  1066.     Detach(D_REMOTE);
  1067.       else
  1068. #endif
  1069.       SigHup(SIGARG);
  1070.       break;
  1071.     default:
  1072.       Msg(0, "Invalid message (type %d).", m.type);
  1073.     }
  1074. }
  1075.  
  1076. #if defined(_SEQUENT_) && !defined(NAMEDPIPE)
  1077. #undef connect
  1078.  
  1079. sconnect(s, sapp, len)
  1080. int s, len;
  1081. struct sockaddr *sapp;
  1082. {
  1083.   register struct sockaddr_un *sap;
  1084.   struct stat st;
  1085.   int x;
  1086.  
  1087.   sap = (struct sockaddr_un *)sapp;
  1088.   if (stat(sap->sun_path,&st))
  1089.     return -1;
  1090.   chmod(sap->sun_path, 0);
  1091.   x = connect(s, (struct sockaddr *) sap, len);
  1092.   chmod(sap->sun_path, st.st_mode);
  1093.   return x;
  1094. }
  1095. #endif
  1096.